//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

use git2::{BranchType, Error, Repository};
use serde::Serialize;
use std::path::PathBuf;

#[derive(Serialize)]
struct HeadInfo {
    commit_id: String,
    branch_name: String,
    tag_name: String,
    detached: bool,
}

pub fn exec(git_path: PathBuf) -> Result<(), Error> {
    let repo = Repository::open(git_path);
    if repo.is_err() {
        return Err(repo.err().unwrap());
    }
    let repo = repo.unwrap();

    let mut ret_info = HeadInfo {
        commit_id: "".into(),
        branch_name: "".into(),
        tag_name: "".into(),
        detached: false,
    };

    let head_ref = repo.head();
    if head_ref.is_err() {
        return Err(head_ref.err().unwrap());
    }
    let head_ref = head_ref.unwrap();
    let head_oid = head_ref.target();
    if head_oid.is_some() {
        ret_info.commit_id = head_oid.unwrap().to_string();
    }
    let detached = repo.head_detached();
    if detached.is_err() {
        return Err(detached.err().unwrap());
    }
    ret_info.detached = detached.unwrap();

    let branchs = repo.branches(Some(BranchType::Local));
    if branchs.is_err() {
        return Err(branchs.err().unwrap());
    }
    let branchs = branchs.unwrap();
    for branch in branchs {
        if branch.is_err() {
            continue;
        }

        let branch = branch.unwrap();
        let mut branch_name = String::from("");
        let name = branch.0.name();
        if name.is_ok() {
            let name = name.unwrap();
            branch_name = name.unwrap_or_default().into();
        }
        if branch.0.is_head() {
            ret_info.branch_name = branch_name.clone();
        }
    }

    let _ = repo.tag_foreach(|oid, name| {
        let obj = repo.find_object(oid, None);
        if obj.is_err() {
            return true;
        }
        let obj = obj.unwrap();
        let commit = obj.peel_to_commit();
        if commit.is_err() {
            return true;
        }
        let commit = commit.unwrap();
        if commit.id().to_string() == ret_info.commit_id {
            ret_info.tag_name = String::from_utf8_lossy(name).to_string().replace("refs/tags/", "");
        }
        return true;
    });

    println!("{}", serde_json::to_string(&ret_info).unwrap());

    Ok(())
}
